﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using GalaSoft.MvvmLight;
using MusicExplorer.Helper;
using MusicExplorer.Internals;
using MusicExplorer.WebRepository;
using MusicExplorer.WebRepository.Interface;
using MusicExplorer.WebRepository.Service;
using MusicExplorer.Wrappers;

namespace MusicExplorer.ViewModel
{
    public class WebRepositoryTreeViewModel : ViewModelBase
    {
        private readonly MainWindowViewModel m_parent;
        public MainWindowViewModel Parent { get { return m_parent; } }

        public WebRepositoryTreeViewModel(MainWindowViewModel parent)
        {
            m_parent = parent;

            m_webRepositories = new ObservableCollection<WebRepositoryWrapper>();
            m_groupsWebRepositories = new ObservableCollection<WebRepositoryGroupWrapper>();

            Task.Factory.StartNew(() => LoadWebRepositories());
        }

        #region FUNCTIONS

        public void RefreshTree()
        {
            //if (SelectedWebRepository != null)
            //{
            //    Parent.TrackList.TaskTracksLoading = null;
            //    Parent.TrackList.Tracks.Clear();
            //    Parent.Player.Stop();
            GroupsWebRepositories.Clear();
            WebRepositories.Clear();
            Task.Factory.StartNew(() => LoadWebRepositories());
            //}
        }

        private void LoadWebRepositories()
        {
            Parent.Log.SetLog("Loading of web repositories...", LogTypeEnum.Loading);
            var repos = new ObservableCollection<WebRepositoryWrapper>();
            foreach (var repo in ServiceWebRepository.GetAllWebRepositoryWithoutType())
            {
                var repoBase = WebRepositoryBase.CreateWebRepository(repo);
                if (repoBase == null) continue;
                var wrapper = new WebRepositoryWrapper(Parent, repoBase);
                wrapper.PropertyChanged += WebRepositoryChanged;
                repos.Add(wrapper);
            }

            var groups = new ObservableCollection<WebRepositoryGroupWrapper>();
            foreach (var group in ServiceWebRepository.GetAllWebRepositoryTypesWithRepo())
            {
                var g = new WebRepositoryGroupWrapper(Parent, group);
                foreach (var repo in group.WEB_REPOSITORY.Where(wp => wp.web_repo_visibility).OrderBy(wp => wp.web_repo_order))
                {
                    var repoBase = WebRepositoryBase.CreateWebRepository(repo);
                    if (repoBase == null) continue;
                    var wrapper = new WebRepositoryWrapper(Parent, repoBase);
                    wrapper.PropertyChanged += WebRepositoryChanged;
                    g.WebRepositories.Add(wrapper);
                }

                groups.Add(g);
            }

            MusicExplorerHelper.ExecuteInUIThread(() =>
                {
                    foreach (var wr in repos)
                    {
                        WebRepositories.Add(wr);
                    }

                    foreach (var g in groups)
                    {
                        GroupsWebRepositories.Add(g);
                    }
                });

            Parent.Log.ResetLog();
        }

        void WebRepositoryChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "IsSelected")
            {
                if((sender as WebRepositoryWrapper).IsSelected)
                    SelectedWebRepository = (WebRepositoryWrapper)sender;
            }
        }

        #endregion

        #region PROPERTIES

        private WebRepositoryWrapper m_selectedWebRepositoryList;
        public WebRepositoryWrapper SelectedWebRepositoryList
        {
            get { return m_selectedWebRepositoryList; }
            set
            {
                if (m_selectedWebRepositoryList != value)
                {
                    m_selectedWebRepositoryList = value;
                    RaisePropertyChanged("SelectedWebRepositoryList");
                }
            }
        }

        private WebRepositoryWrapper m_selectedWebRepository;
        public WebRepositoryWrapper SelectedWebRepository
        {
            get { return m_selectedWebRepository; }
            set
            {
                if (m_selectedWebRepository != value)
                {
                    m_selectedWebRepository = value;
                    RaisePropertyChanged("SelectedWebRepository");

                    if (m_selectedWebRepository.WebRepository is IGroupFilterWebRepository || m_selectedWebRepository.WebRepository is IArtistFilterWebRepository || m_selectedWebRepository.WebRepository is ILabelFilterWebRepository)
                        Parent.DetailTree.SelectedWebRepository = m_selectedWebRepository;
                    else
                    {
                        if (Parent.DetailTree.SelectedWebRepository != null)
                        {
                            Parent.DetailTree.SelectedWebRepository.IsLoading = false;
                            Parent.DetailTree.StopCurrentTreeLoading();
                            Parent.DetailTree.SelectedWebRepository = null;
                        }
                        Parent.TrackList.Load(m_selectedWebRepository);
                    }
                }
            }
        }

        private ObservableCollection<WebRepositoryGroupWrapper> m_groupsWebRepositories;
        public ObservableCollection<WebRepositoryGroupWrapper> GroupsWebRepositories
        {
            get { return m_groupsWebRepositories; }
            set
            {
                if (m_groupsWebRepositories != value)
                {
                    m_groupsWebRepositories = value;
                    RaisePropertyChanged("GroupsWebRepositories");
                }
            }
        }

        private ObservableCollection<WebRepositoryWrapper> m_webRepositories;
        public ObservableCollection<WebRepositoryWrapper> WebRepositories
        {
            get { return m_webRepositories; }
            set
            {
                if (m_webRepositories != value)
                {
                    m_webRepositories = value;
                    RaisePropertyChanged("WebRepositories");
                }
            }
        }

        #endregion
    }
}
